#ifndef __GS_HASHTABLE_H__
#define __GS_HASHTABLE_H__

#include <stdint.h>
#include <pthread.h>

#ifndef __x86_64__
#error "hashtable just support 64bit system"
#endif

struct Slot;

typedef struct HashTable {
  uint32_t (*hash)(const void*);
  int (*equals)(const void*, const void*);
  void (*freekey)(void*);
  void (*freeval)(void*);
  pthread_rwlock_t lock;
  int length;
  struct Slot* slots[];
} HashTable;

typedef struct HashTableIterator {
  HashTable* table;
  int idx;
  void** next;
} HashTableIterator;

HashTable* HashTableCreate(int capacity, uint32_t (*hash)(const void*), int (*equals)(const void*, const void*), void (*freekey)(void*), void (*freeval)(void*));
HashTable* IntKeyHashTableCreate(int capacity, void (*freeval)(void*));
HashTable* StringKeyHashTableCreate(int capacity, void (*freeval)(void*));
void HashTableDestroy(void* data);
void HashTableSafeClear(HashTable* table);
const void* HashTableFind(HashTable* table, const void* key);
void* HashTableRemove(HashTable* table, const void* key);
int HashTableInsert(HashTable* table, void* key, void* val);
HashTableIterator HashTableGetIterator(HashTable* table);
void* HashTableRemoveNext(HashTableIterator* itr);
void* HashTableNext(HashTableIterator* itr);
const void* HashTableSafeFind(HashTable* table, const void* key);
void* HashTableSafeRemove(HashTable* table, const void* key);
int HashTableSafeInsert(HashTable* table, void* key, void* val);

#endif
